home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-07  |  6.9 KB  |  302 lines

  1. /**
  2.    GRAB Graph Layout and Browser System
  3.  
  4.    Copyright (c) 1986, 1988 Regents of the University of California
  5.    Copyright (c) 1989, Tera Computer Company
  6.  **/
  7.  
  8.   /**
  9.      misc.c -- miscellaneous routines:  various interfaces
  10.      for redrawing and laying out the graph, plus the Quit routine
  11.    **/
  12.  
  13. #include "malloc.h"
  14. #include <stdio.h>
  15. #include <time.h>
  16.  
  17. #include "attribute.h"
  18. #include "digraph.h"
  19. #include "screen.h"
  20. #include "globals.h"
  21. #include "scrdep.h"
  22. #include "interf.h"
  23. #include "cursor.h"
  24.  
  25. void GetSBounds();
  26. void DoGraph();
  27.  
  28. static BOOL layed_out = FALSE;
  29.  
  30. BOOL ReadIn()
  31.   /**
  32.      Read a graph from a file.  Keep a record if it was layed out.
  33.      Return true if the graph was actually read.
  34.    **/
  35. {
  36.     char *buf;
  37.     FILE *graph_file;
  38.     BOOL okay = FALSE;
  39.     DIGRAPH *InitDigraph();
  40.  
  41.     IChangeStatusLine("Reading in graph", TRUE);
  42.     ISetCursor(waitC);
  43.  
  44.     digraph = InitDigraph();
  45.     graphChanged = FALSE;
  46.     ckpt_done = FALSE;
  47.  
  48.     if (*name != '\0' && (graph_file = fopen(name, "r")) != NULL) 
  49.     {
  50.     okay = TRUE;
  51.     layed_out = read_graph(digraph, graph_file);
  52.     fclose(graph_file);
  53.     }
  54.     else if (*name != '\0')
  55.     {
  56.     buf = (char *) malloc(MAXLINE * sizeof(char));
  57.     sprintf(buf, "Couldn't open %s", name);
  58.     IChangeStatusLine(buf, FALSE);
  59.     dispose(buf);
  60.     }
  61.     else
  62.     {
  63.     IChangeStatusLine("No file to read", FALSE);
  64.     }
  65.  
  66.     if (NNodeAttr(digraph) == 0)
  67.       /* if no digraph read, give some default attributes */
  68.     {
  69.     char **attr;
  70.  
  71.     attr = (char **) malloc(sizeof(char *));
  72.     strsave(attr[0], "label");
  73.     InitNodeAttrs(digraph, attr, 1, 0);
  74.  
  75.       /* have to make separate space for edge attributes */
  76.     attr = (char **) malloc(sizeof(char *));
  77.     strsave(attr[0], "label");
  78.     InitEdgeAttrs(digraph, attr, 1, 0);
  79.     }
  80.  
  81.     IUnsetCursor();
  82.     return okay;
  83. }
  84.  
  85. DisplayReadGraph()
  86.   /**
  87.      we've just called ReadIn.  Lay out the graph if need be.
  88.      Then display it
  89.    **/
  90. {
  91.     if (digraph->lastnode != -1)  /* there are nodes to draw */
  92.     {
  93.         if (!layed_out)
  94.         {
  95.             IChangeStatusLine("Laying out graph", TRUE);
  96.             ISetCursor(waitC);
  97.         FixUp();
  98.         }
  99.         else 
  100.         {
  101.         IChangeStatusLine("Drawing graph", TRUE);
  102.             ISetCursor(waitC);
  103.     }
  104.     }
  105.  
  106.     DisplayNewGraph();
  107.     IUnsetCursor();
  108. }
  109.     
  110. DisplayNewGraph()
  111.   /**
  112.      We've read a new graph, so display it.  Then show the graph name,
  113.      the file name, set up the graph attributes window, set up the
  114.      pan and zoom gradients
  115.    **/
  116. {
  117.     int a, b, c, d, e, f, width, height;
  118.  
  119.     StartDisp();
  120.     IChangeGraphName(Title(digraph));
  121.     IChangeFileName(name);
  122.     ISetAttrNames(digraph->node_att_names, digraph->edge_att_names, 
  123.               NNodeAttr(digraph), NEdgeAttr(digraph));
  124.     IGetBounds(&a, &b, &c, &d, &e, &f, &width, &height);
  125.     IChangeZGrad(zoomGradient);
  126.     IChangePGrad((int) (panGradient * width), (int) (panGradient * height));
  127. }
  128.  
  129. write_out()
  130.   /* write the digraph to a file */
  131. {
  132.     FILE *graph_file;
  133.     char *buf;
  134.  
  135.     if (digraph == NULL) 
  136.     {
  137.         IChangeStatusLine("No digraph to save", FALSE);
  138.         return;
  139.     }
  140.  
  141.     if ((graph_file = fopen(name, "w")) == NULL) 
  142.     {
  143.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  144.         sprintf(buf, "Can't write to %s", name);
  145.     IChangeStatusLine(buf, FALSE);
  146.     dispose(buf);
  147.         return;
  148.     }
  149.  
  150.     IChangeStatusLine("Writing out graph", TRUE);
  151.     write_graph(digraph, graph_file);
  152.  
  153.     fclose(graph_file);
  154.  
  155.     IChangeStatusLine("Done", FALSE);
  156.     graphChanged = FALSE;    /* graph written out, so change flag */
  157. }
  158.  
  159. FixUp()
  160.   /* layout the graph */
  161. {
  162.     long clock;
  163.  
  164.     if (digraph == NULL) 
  165.     {
  166.     return;
  167.     }
  168.  
  169.     if (printLayoutTime) 
  170.     {
  171.     clock = time(NULL);
  172.     printf("time before layout: %s", ctime(&clock));
  173.     }
  174.  
  175.     make_proper(digraph);
  176.  
  177.     if (stopInLayout == STOP_AFTER_MAKEPROPER) 
  178.     {
  179.     quick_layout_levels(digraph);
  180.     goto leave;
  181.     }
  182.  
  183.     minimize_crossings(digraph);
  184.  
  185.     if (stopInLayout == STOP_AFTER_MIN_CROSSING) 
  186.     {
  187.     quick_layout_levels(digraph);
  188.     goto leave;
  189.     }
  190.  
  191.     layout_levels(digraph);
  192.  
  193.   leave:
  194.     if (printLayoutTime) 
  195.     {
  196.     clock = time(0);
  197.     printf("time after layout: %s", ctime(&clock));
  198.     }
  199. }
  200.  
  201. StartDisp()
  202.   /**
  203.      display the graph centered in the graph area.  No need to do all 
  204.      the extra hoohah for a new graph because it isn't one.  
  205.      Set up the fonts, too.
  206.    **/
  207. {
  208.     long clock;
  209.  
  210.     IInitFonts();
  211.  
  212.     FindRange(digraph, &screen.absview);
  213.     MakeMinAbsview(&screen.absview);
  214.  
  215.     ICenterGraph();
  216.     DoGraph();
  217.  
  218.     if (printLayoutTime) 
  219.     {
  220.     clock = time(0);
  221.     printf("time after display: %s", ctime(&clock));
  222.     }
  223. }
  224.  
  225.   /* Make sure the absview covers only the necessary area */
  226. MakeMinAbsview(absview)
  227. BOX *absview;
  228. {
  229.     int xCenter, yCenter;
  230.  
  231.     if (absview->max_x - absview->min_x < MIN_ABS_X_SIZE &&
  232.     absview->max_y - absview->min_y < MIN_ABS_Y_SIZE) 
  233.     {
  234.     xCenter = ((absview->max_x - absview->min_x) / 2) + absview->min_x;
  235.     absview->min_x = xCenter - (MIN_ABS_X_SIZE / 2);
  236.     absview->max_x = xCenter + (MIN_ABS_X_SIZE / 2);
  237.  
  238.     yCenter = ((absview->max_y - absview->min_y) / 2) + absview->min_y;
  239.     absview->min_y = yCenter - (MIN_ABS_Y_SIZE / 2);
  240.     absview->max_y = yCenter + (MIN_ABS_Y_SIZE / 2);
  241.     }
  242. }
  243.  
  244.   /* return the size of the screen */
  245. void GetSBounds (x0, y0, width, height)
  246. int *x0, *y0, *width, *height;
  247. {
  248.     *x0 = screen.canvas.min_x - BORDER_SIZE;
  249.     *y0 = screen.canvas.min_y - BORDER_SIZE;
  250.     *width = screen.canvas.max_x - *x0 + BORDER_SIZE;
  251.     *height = screen.canvas.max_y - *y0 + BORDER_SIZE;
  252. }
  253.  
  254.   /**
  255.      set up the screen variable to match the canvas and perspective
  256.      for the graph area
  257.    **/
  258. ReCalcScreen()
  259. {
  260.     int curx, cury, curwidth, curheight, x0, y0, width, height;
  261.  
  262.     IGetBounds(&x0, &y0, &width, &height, &curx, &cury, &curwidth, &curheight);
  263.  
  264.     screen.display.min_x = curx;
  265.     screen.display.min_y = cury;
  266.     screen.display.max_x = curx + curwidth;
  267.     screen.display.max_y = cury + curheight;
  268.  
  269.       /* leave a little margin */
  270.     screen.canvas.min_x = x0 + BORDER_SIZE;        
  271.     screen.canvas.min_y = y0 + BORDER_SIZE;
  272.     screen.canvas.max_x = x0 + width - BORDER_SIZE;
  273.     screen.canvas.max_y = y0 + height - BORDER_SIZE;
  274.  
  275.       /* set up the zoom factors */
  276.     screen.zoom.xzoom = (float) (screen.absview.max_x - screen.absview.min_x) /
  277.             (float) (screen.canvas.max_x - screen.canvas.min_x);
  278.     screen.zoom.yzoom = (float) (screen.absview.max_y - screen.absview.min_y) /
  279.             (float) (screen.canvas.max_y - screen.canvas.min_y);
  280.  
  281.       /* find what part of the absview is visible on the screen */
  282.     screen.bound.min_x = SCRX_TO_ABSX(&screen, 0);
  283.     screen.bound.min_y = SCRY_TO_ABSY(&screen, 0);
  284.     screen.bound.max_x = SCRX_TO_ABSX(&screen, curwidth);
  285.     screen.bound.max_y = SCRY_TO_ABSY(&screen, curheight);
  286. }
  287.  
  288. void DoQuit()
  289. {
  290.       /* graph hasn't changed, so we just leave */
  291.     if (graphChanged == FALSE)     
  292.     {
  293.     exit(0);
  294.     }
  295.  
  296.       /* else we ask the user if he really wants to quit */
  297.     if (IConfirm("No write since last change.  Quit anyway?") == 'y') 
  298.     {
  299.     exit(0);
  300.     }
  301. }
  302.